package com.brainwave.bluetooth;

import com.brainwave.utils.Constants;
import com.brainwave.utils.Logger;

import java.util.ArrayList;
import java.util.List;

/**
 * NeuroSky协议解析类
 * 负责解析从NeuroSky设备接收的数据包
 */
public class NeuroSkyProtocol {
    private static final String TAG = "NeuroSkyProtocol";
    
    // 协议常量
    private static final byte SYNC_BYTE = (byte) 0xAA;
    private static final byte EXCODE_BYTE = (byte) 0x55;
    
    // 数据包解析状态
    private enum ParseState {
        SYNC,
        SYNC_CHECK,
        PAYLOAD_LENGTH,
        PAYLOAD,
        CHECKSUM
    }
    
    // 解析状态
    private ParseState parseState = ParseState.SYNC;
    private int payloadLength = 0;
    private int payloadBytesReceived = 0;
    private int checksum = 0;
    private int generatedChecksum = 0;
    private List<Byte> payloadData = new ArrayList<>();
    
    // 数据监听器
    private List<NeuroSkyDataListener> listeners = new ArrayList<>();
    
    /**
     * NeuroSky数据监听器接口
     */
    public interface NeuroSkyDataListener {
        void onPoorSignalReceived(int poorSignal);
        void onAttentionReceived(int attention);
        void onMeditationReceived(int meditation);
        void onBlinkReceived(int blinkStrength);
        void onRawDataReceived(int rawValue);
        void onEegPowerReceived(EegPowerData eegPower);
        void onParseError(String error);
    }
    
    /**
     * EEG功率数据类
     */
    public static class EegPowerData {
        public int delta;      // 0.5-2.75Hz
        public int theta;      // 3.5-6.75Hz
        public int lowAlpha;   // 7.5-9.25Hz
        public int highAlpha;  // 10-11.75Hz
        public int lowBeta;    // 13-16.75Hz
        public int highBeta;   // 18-29.75Hz
        public int lowGamma;   // 31-39.75Hz
        public int highGamma;  // 41-49.75Hz
        
        @Override
        public String toString() {
            return String.format("EegPower{delta=%d, theta=%d, lowAlpha=%d, highAlpha=%d, " +
                    "lowBeta=%d, highBeta=%d, lowGamma=%d, highGamma=%d}",
                    delta, theta, lowAlpha, highAlpha, lowBeta, highBeta, lowGamma, highGamma);
        }
    }
    
    /**
     * 添加数据监听器
     */
    public void addDataListener(NeuroSkyDataListener listener) {
        if (!listeners.contains(listener)) {
            listeners.add(listener);
        }
    }
    
    /**
     * 移除数据监听器
     */
    public void removeDataListener(NeuroSkyDataListener listener) {
        listeners.remove(listener);
    }
    
    /**
     * 解析接收到的数据
     */
    public void parseData(byte[] data) {
        for (byte b : data) {
            parseByte(b & 0xFF);
        }
    }
    
    /**
     * 解析单个字节
     */
    private void parseByte(int byteValue) {
        switch (parseState) {
            case SYNC:
                if (byteValue == (SYNC_BYTE & 0xFF)) {
                    parseState = ParseState.SYNC_CHECK;
                }
                break;
                
            case SYNC_CHECK:
                if (byteValue == (SYNC_BYTE & 0xFF)) {
                    parseState = ParseState.PAYLOAD_LENGTH;
                } else {
                    parseState = ParseState.SYNC;
                    parseByte(byteValue); // 重新处理这个字节
                }
                break;
                
            case PAYLOAD_LENGTH:
                payloadLength = byteValue;
                if (payloadLength > 169) {
                    // 无效的载荷长度
                    notifyParseError("Invalid payload length: " + payloadLength);
                    resetParser();
                } else if (payloadLength == 0) {
                    parseState = ParseState.CHECKSUM;
                } else {
                    payloadBytesReceived = 0;
                    generatedChecksum = 0;
                    payloadData.clear();
                    parseState = ParseState.PAYLOAD;
                }
                break;
                
            case PAYLOAD:
                payloadData.add((byte) byteValue);
                generatedChecksum += byteValue;
                payloadBytesReceived++;
                
                if (payloadBytesReceived >= payloadLength) {
                    parseState = ParseState.CHECKSUM;
                }
                break;
                
            case CHECKSUM:
                checksum = byteValue;
                generatedChecksum = (~generatedChecksum) & 0xFF;
                
                if (checksum == generatedChecksum) {
                    // 校验成功，解析载荷数据
                    parsePayload();
                } else {
                    notifyParseError("Checksum mismatch: expected " + generatedChecksum + ", got " + checksum);
                }
                
                resetParser();
                break;
        }
    }
    
    /**
     * 解析载荷数据
     */
    private void parsePayload() {
        int i = 0;
        while (i < payloadData.size()) {
            int extendedCodeLevel = 0;
            
            // 处理扩展代码
            while (i < payloadData.size() && (payloadData.get(i) & 0xFF) == (EXCODE_BYTE & 0xFF)) {
                extendedCodeLevel++;
                i++;
            }
            
            if (i >= payloadData.size()) {
                break;
            }
            
            int code = payloadData.get(i++) & 0xFF;
            
            if (code >= 0x80) {
                // 多字节值
                int length = code - 0x80;
                if (i + length > payloadData.size()) {
                    notifyParseError("Insufficient data for multi-byte value");
                    break;
                }
                
                byte[] valueBytes = new byte[length];
                for (int j = 0; j < length; j++) {
                    valueBytes[j] = payloadData.get(i++);
                }
                
                parseMultiByteValue(code, valueBytes, extendedCodeLevel);
            } else {
                // 单字节值
                if (i >= payloadData.size()) {
                    notifyParseError("Missing single-byte value");
                    break;
                }
                
                int value = payloadData.get(i++) & 0xFF;
                parseSingleByteValue(code, value, extendedCodeLevel);
            }
        }
    }
    
    /**
     * 解析单字节值
     */
    private void parseSingleByteValue(int code, int value, int extendedCodeLevel) {
        if (extendedCodeLevel == 0) {
            switch (code) {
                case Constants.POOR_SIGNAL_QUALITY:
                    notifyPoorSignal(value);
                    break;
                    
                case Constants.ATTENTION_ESENSE:
                    notifyAttention(value);
                    break;
                    
                case Constants.MEDITATION_ESENSE:
                    notifyMeditation(value);
                    break;
                    
                case Constants.BLINK_STRENGTH:
                    notifyBlink(value);
                    break;
                    
                default:
                    Logger.d(TAG, "Unknown single-byte code: 0x" + Integer.toHexString(code) + ", value: " + value);
                    break;
            }
        }
    }
    
    /**
     * 解析多字节值
     */
    private void parseMultiByteValue(int code, byte[] valueBytes, int extendedCodeLevel) {
        if (extendedCodeLevel == 0) {
            switch (code) {
                case Constants.RAW_WAVE_VALUE:
                    if (valueBytes.length == 2) {
                        int rawValue = ((valueBytes[0] & 0xFF) << 8) | (valueBytes[1] & 0xFF);
                        // 转换为有符号16位整数
                        if (rawValue > 32767) {
                            rawValue -= 65536;
                        }
                        notifyRawData(rawValue);
                    }
                    break;
                    
                case Constants.ASIC_EEG_POWER:
                    if (valueBytes.length == 24) {
                        parseEegPowerData(valueBytes);
                    } else {
                        Logger.w(TAG, "Invalid EEG power data length: " + valueBytes.length);
                    }
                    break;
                    
                default:
                    Logger.d(TAG, "Unknown multi-byte code: 0x" + Integer.toHexString(code) + 
                            ", length: " + valueBytes.length);
                    break;
            }
        }
    }
    
    /**
     * 解析EEG功率数据
     */
    private void parseEegPowerData(byte[] data) {
        if (data.length != 24) {
            return;
        }
        
        EegPowerData eegPower = new EegPowerData();
        
        // 每个频段占用3个字节（24位整数）
        eegPower.delta = parse24BitInt(data, 0);
        eegPower.theta = parse24BitInt(data, 3);
        eegPower.lowAlpha = parse24BitInt(data, 6);
        eegPower.highAlpha = parse24BitInt(data, 9);
        eegPower.lowBeta = parse24BitInt(data, 12);
        eegPower.highBeta = parse24BitInt(data, 15);
        eegPower.lowGamma = parse24BitInt(data, 18);
        eegPower.highGamma = parse24BitInt(data, 21);
        
        notifyEegPower(eegPower);
    }
    
    /**
     * 解析24位整数
     */
    private int parse24BitInt(byte[] data, int offset) {
        return ((data[offset] & 0xFF) << 16) | 
               ((data[offset + 1] & 0xFF) << 8) | 
               (data[offset + 2] & 0xFF);
    }
    
    /**
     * 重置解析器状态
     */
    private void resetParser() {
        parseState = ParseState.SYNC;
        payloadLength = 0;
        payloadBytesReceived = 0;
        checksum = 0;
        generatedChecksum = 0;
        payloadData.clear();
    }
    
    /**
     * 通知信号质量
     */
    private void notifyPoorSignal(int poorSignal) {
        Logger.d(TAG, "Poor signal: " + poorSignal);
        for (NeuroSkyDataListener listener : listeners) {
            listener.onPoorSignalReceived(poorSignal);
        }
    }
    
    /**
     * 通知注意力值
     */
    private void notifyAttention(int attention) {
        Logger.d(TAG, "Attention: " + attention);
        for (NeuroSkyDataListener listener : listeners) {
            listener.onAttentionReceived(attention);
        }
    }
    
    /**
     * 通知冥想值
     */
    private void notifyMeditation(int meditation) {
        Logger.d(TAG, "Meditation: " + meditation);
        for (NeuroSkyDataListener listener : listeners) {
            listener.onMeditationReceived(meditation);
        }
    }
    
    /**
     * 通知眨眼强度
     */
    private void notifyBlink(int blinkStrength) {
        Logger.d(TAG, "Blink strength: " + blinkStrength);
        for (NeuroSkyDataListener listener : listeners) {
            listener.onBlinkReceived(blinkStrength);
        }
    }
    
    /**
     * 通知原始数据
     */
    private void notifyRawData(int rawValue) {
        for (NeuroSkyDataListener listener : listeners) {
            listener.onRawDataReceived(rawValue);
        }
    }
    
    /**
     * 通知EEG功率数据
     */
    private void notifyEegPower(EegPowerData eegPower) {
        Logger.d(TAG, "EEG Power: " + eegPower.toString());
        for (NeuroSkyDataListener listener : listeners) {
            listener.onEegPowerReceived(eegPower);
        }
    }
    
    /**
     * 通知解析错误
     */
    private void notifyParseError(String error) {
        Logger.e(TAG, "Parse error: " + error);
        for (NeuroSkyDataListener listener : listeners) {
            listener.onParseError(error);
        }
    }
    
    /**
     * 清理资源
     */
    public void destroy() {
        listeners.clear();
        resetParser();
        Logger.d(TAG, "NeuroSkyProtocol destroyed");
    }
}